package com.weijin.service.impl;

import ch.qos.logback.core.util.TimeUtil;
import com.weijin.exception.AppException;
import com.weijin.mapper.RecordMapper;
import com.weijin.model.entities.ExceptionRecordInfo;
import com.weijin.model.entities.Record;
import com.weijin.model.entities.User;
import com.weijin.model.entities.WorkRecord;
import com.weijin.model.enums.AttendanceStatus;
import com.weijin.model.enums.AttendanceType;
import com.weijin.model.enums.ExceptionCode;
import com.weijin.model.from.AttendanceFrom;
import com.weijin.service.IRecordService;
import com.weijin.service.IExceptionRecordInfoService;
import com.weijin.service.IUserService;
import com.weijin.service.IWorkRecordService;
import com.weijin.utils.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;

/**
 * 考勤服务接口实现类
 *
 * @Author WeiJin
 * @Version 1.0
 * @Date 2025/3/28 11:06
 */
@Service
public class RecordServiceImpl implements IRecordService {

    @Autowired
    private IUserService userService;
    @Autowired
    private IExceptionRecordInfoService exceptionRecordInfoService;
    @Autowired
    private IWorkRecordService workRecordService;
    @Autowired
    private RecordMapper recordMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Record signIn(AttendanceFrom attendanceFrom) {
        // 参数非空校验
        if (Objects.isNull(attendanceFrom)) {
            throw new AppException(ExceptionCode.REQUEST_PARAMETER_IS_NULL);
        }
        // 验证员工信息
        User user = userService.queryUserById(attendanceFrom.getUserId());
        if (Objects.isNull(user)) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }
        LocalDateTime signInTime = DateTimeUtil.convertLocalDateTime(attendanceFrom.getTime());
        // 初步构建用户打卡信息
        Record record = new Record(attendanceFrom.getUserId(), signInTime, AttendanceType.SIGN_IN);
        // 判断模拟签到时间是否在早上九点之前
        boolean isLate = DateTimeUtil.isLate(signInTime);
        if (isLate) {
            // 迟到设置考勤状态为迟到
            record.setStatus(AttendanceStatus.LATE);
            // 计算迟到时长 单位：秒
            Long seconds = DateTimeUtil.lateTime(signInTime);
            // 记录迟到情况
            ExceptionRecordInfo exceptionRecordInfo = new ExceptionRecordInfo(user.getId(), user.getName(),
                    signInTime, AttendanceType.SIGN_IN, AttendanceStatus.LATE, seconds);
            exceptionRecordInfoService.saveExceptionRecord(exceptionRecordInfo);
        } else {
            // 没迟到设置考勤状态为正常
            record.setStatus(AttendanceStatus.NORMAL);
        }

        // 保存签到记录
        recordMapper.insert(record);
        // 返回签到记录
        return record;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Record signOut(AttendanceFrom attendanceFrom) {
        // 参数非空校验
        if (Objects.isNull(attendanceFrom)) {
            throw new AppException(ExceptionCode.REQUEST_PARAMETER_IS_NULL);
        }
        // 验证员工信息
        User user = userService.queryUserById(attendanceFrom.getUserId());
        if (Objects.isNull(user)) {
            throw new AppException(ExceptionCode.USER_IS_NULL);
        }
        LocalDateTime signOutTime = DateTimeUtil.convertLocalDateTime(attendanceFrom.getTime());
        // 初步构建用户签退信息
        Record record = new Record(attendanceFrom.getUserId(), signOutTime, AttendanceType.SIGN_OUT);
        // 判断是否早退
        boolean isEarly = DateTimeUtil.isEarly(signOutTime);
        if (isEarly) {
            // 早退处理
            // 记录为早退
            record.setStatus(AttendanceStatus.LEAVE_EARLY);
            // 保存异常打卡信息
            // 计算早退时长 单位秒
            Long seconds = DateTimeUtil.earlyTime(signOutTime);
            // 记录早退情况
            ExceptionRecordInfo exceptionRecordInfo = new ExceptionRecordInfo(user.getId(), user.getName(),
                    signOutTime, AttendanceType.SIGN_OUT, AttendanceStatus.LEAVE_EARLY, seconds);
            exceptionRecordInfoService.saveExceptionRecord(exceptionRecordInfo);
        } else {
            // 正常签退处理
            record.setStatus(AttendanceStatus.NORMAL);
        }
        // 保存签退记录
        recordMapper.insert(record);
        // 保存用户工作时长
        // 获取今日签到记录
        Record toDaySignInRecord = queryTodaySignInRecord(user.getId(), signOutTime);
        // 计算工作时长
        LocalTime workTime = DateTimeUtil.between(toDaySignInRecord.getTime(), signOutTime);
        // 构建工作记录对象
        WorkRecord workRecord = new WorkRecord(user.getId(), user.getName(), signOutTime.toLocalDate(), workTime,
                toDaySignInRecord.getStatus(), record.getStatus());
        workRecordService.saveWorkRecord(workRecord);
        // 返回打卡记录
        return record;
    }

    @Override
    public Record queryTodaySignInRecord(String userId, LocalDateTime dateTime) {
        // 查询该用户今天的签到记录，可能不止签了一次
        List<Record> records = recordMapper.selectTodayRecord(userId, dateTime);
        if (Objects.isNull(records) || records.isEmpty()) {
            throw new AppException(ExceptionCode.TODAY_NOT_SIGN_IN_RECORD);
        }
        // 只返回最后一次签到信息
        return records.get(0);
    }
}
